from sensorapp import app, db, ma, config
from sensorapp.models import Sensor
from flask import jsonify, redirect, request, url_for
from flask_restful import Resource
from sqlalchemy.sql import func

# https://blog.csdn.net/weixin_40547993/article/details/105857937
# from sqlalchemy import or_, and_
import uuid
import time


class SensorSchema(ma.Schema):
    class Meta:
        # 需要序列化的字段, 只有在这里列出的字段名才会转为 json 数据
        fields = ("uuid", "metric", "type", "value", "time")


# 单个模型数据的序列化
monitor_schema = SensorSchema()
# 多个模型数据的序列化
monitors_schema = SensorSchema(many=True)


def MakeApiResult(status, code, msg=None, data=None):
    if msg == None:
        msg = ""
    if data == None:
        return jsonify({"status": status, "code": code, "msg": msg})
    else:
        return jsonify({"status": status, "code": code, "msg": msg, "data": data})


class SensorUploadApi(Resource):
    def get(self):
        pass

    def post(self):
        """
        上传若干个传感器数据
        访问路径：http://127.0.0.1:9004/api/monitor/upload
        """
        status, code, msg = 0, 1, None
        try:
            for obj in request.json:
                type = obj["type"]
                metric = "value"
                if type == "struct" or type == "ventilator":
                    metric = "status"
                new_monitor = Sensor(
                    id=str(uuid.uuid4()),
                    uuid=obj["uuid"],
                    metric=metric,
                    type=type,
                    value=str(obj["value"]),  # 强制转为string
                    time=obj["time"],
                )
                db.session.add(new_monitor)  # 添加记录
            print(f"上传{len(request.json)}条传感器数据")
            db.session.commit()  # 提交会话
            # return monitor_schema.dump(new_monitor)  # 将下载结果由对象类型转为 python 数据
            status, code, msg = 1, 0, "上传传感器数据成功"
        except Exception as err:
            status, code, msg = 0, 1, err.args
            db.session.rollback()
            print("[SensorUploadApi ERROR]:", err)
        return MakeApiResult(status, code, msg)


class SensorAverageApi(Resource):
    def get(self):
        pass

    def post(self):
        try:
            start = None
            # print("args:", request.args)
            if "start" in request.args:
                start = float(request.args.get("start"))
            else:
                # 以当前时间为时间戳
                start = time.time()
            datas = []
            if "value" in request.json:
                for uuid in request.json["value"]:
                    try:
                        # 方法1: cast类型转换string -> float
                        # result = (
                        #     db.session.query(func.avg(db.cast(Sensor.value, db.Float)))
                        #     .filter(Sensor.uuid == uuid)
                        #     .filter(Sensor.time >= start - config["sensor"]["avg_time"])
                        #     .filter(Sensor.time <= start)
                        #     .scalar()
                        # )
                        # if result != None and abs(result) > 1e-4:
                        #     datas.append({"id": uuid, "value": result})
                        # else:
                        #     raise Exception(
                        #         f"下载[value]类型传感器失败 -> id:{uuid}, 值:{result}"
                        #     )
                        # 方法2: 自行转换
                        query = (
                            db.session.query(Sensor.value)
                            .filter(Sensor.uuid == uuid)
                            .filter(Sensor.time >= start - config["sensor"]["avg_time"])
                            .filter(Sensor.time <= start)
                            .all()
                        )
                        if query != None and len(query) > 0:
                            result = sum([float(x[0]) for x in query]) / len(query)
                            if abs(result) > 1e-4:
                                datas.append({"id": uuid, "value": result})
                                print(
                                    f"下载[value]类型传感器成功 -> id:{uuid}, num:{len(query)}, avg:{result}"
                                )
                            else:
                                raise Exception(
                                    f"下载[value]类型传感器失败 -> id:{uuid}, 值:{result}"
                                )
                        else:
                            raise Exception(f"下载[value]类型传感器失败 -> id:{uuid}")
                    except Exception as err:
                        print("[SensorAverageApi ERROR]:", err)

            if "status" in request.json:
                for uuid in request.json["status"]:
                    try:
                        # -1表示取最后一个
                        query = (
                            db.session.query(Sensor.value)
                            .filter(Sensor.uuid == uuid)
                            .filter(Sensor.time >= start - config["sensor"]["avg_time"])
                            .filter(Sensor.time <= start)
                        )
                        result = query[-1]
                        if query != None and result != None:
                            datas.append({"id": uuid, "value": result[0]})
                            print(
                                f"下载[status]类型传感器成功 -> id:{uuid}, num:{len(query)}个, res:{result}"
                            )
                        else:
                            raise Exception(f"下载[status]类型传感器失败 -> id:{uuid}")
                    except Exception as err:
                        print("[SensorAverageApi ERROR]:", err)
            return MakeApiResult(1, 0, msg="下载平均值成功", data=datas)
        except Exception as e:
            print("[SensorAverageApi ERROR]:", e)
            return MakeApiResult(0, 1, msg=e.args)


# CALCULATE_API = "https://1825138619804807.cn-zhangjiakou.fc.aliyuncs.com/2016-08-15/proxy/jl/api/v1/calculate"
# MONITOR_API = "https://1825138619804807.cn-zhangjiakou.fc.aliyuncs.com/2016-08-15/proxy/jl/api/monitor/average?start={0}"

# @app.before_request
# def myredirect():
#     url = request.path
#     if url == '2016-08-15/proxy/jl/api/v1/calculate':

#     u = url.split("/")
#     if len(u) >= 3:
#         if u[2] == "admin":
#             if u[3] != "login":
#                 if not "username" in session:
#                     session["newurl"] = request.path
#                     return redirect(url_for("get_page_admin_login"))
# if not request.path == "/":

#     username = request.args.get("username")
#     if not username:
#         return redirect("/")
#     else:
#         print "success"


@app.route("/", methods=["GET"])
def index():
    # 跳转到 api对应的地址
    # return redirect("/api/v1/monitors")
    return "hello world"
